/**
 * 景区地图查看器组件
 * 基于HospitalMapViewer扩展，支持景区数据绑定功能
 */

'use client'

import React, { useRef, useEffect, useState, useCallback, useImperativeHandle, forwardRef } from 'react'
import { toast } from 'sonner'
import * as THREE from 'three'
import AMapLoader from '@amap/amap-jsapi-loader'
import { AMAP_KEY } from '@/lib/config'
import { StoreBindingModal } from './StoreBindingModal'
import { FacilityBindingModal } from './FacilityBindingModal'
import { getStoresByAttraction } from '@/lib/api/store'
import { getFacilitiesByAttraction } from '@/lib/api/facility'

// 类型定义
declare global {
  interface Window {
    AMap: any
    Loca: any
  }
}

interface AttractionData {
  id: string
  name: string
  description: string
  center: [number, number]
  modelPath: string
  floors: string[]
}

interface StoreMarkerData {
  id: string
  name: string
  business: string
  position: [number, number]
  status: string
}

interface FacilityMarkerData {
  id: string
  name: string
  type: string
  position: [number, number]
  status: string
}

interface AttractionMapViewerProps {
  attraction?: AttractionData
  amapKey?: string
  zoom?: number
  className?: string
  onDataChange?: () => void
}

export interface AttractionMapViewerRef {
  refreshStores: () => void
  refreshFacilities: () => void
  refreshModel: () => void
  flyTo: (lngLat: [number, number], zoom?: number) => void
}

export const AttractionMapViewer = forwardRef<AttractionMapViewerRef, AttractionMapViewerProps>(({
  attraction,
  amapKey = AMAP_KEY,
  zoom = 16,
  className = "w-full h-full",
  onDataChange
}, ref) => {
  
  const containerRef = useRef<HTMLDivElement>(null)
  const AMapRef = useRef<any>(null)
  const mapRef = useRef<any>(null)
  const initOnceRef = useRef<boolean>(false)
  const sceneRef = useRef<THREE.Scene>(new THREE.Scene())
  const cameraRef = useRef<THREE.PerspectiveCamera>()
  const rendererRef = useRef<THREE.WebGLRenderer>()
  const modelGroupRef = useRef<THREE.Group>(new THREE.Group())
  const rayStateRef = useRef({
    raycaster: new THREE.Raycaster(),
    mouse: new THREE.Vector2()
  })

  // 状态管理
  const [mapLoaded, setMapLoaded] = useState(false)
  const [mapLoadFailed, setMapLoadFailed] = useState(false)
  const [loadError, setLoadError] = useState<string>('')
  const [modelLoaded, setModelLoaded] = useState(false)
  const [stores, setStores] = useState<StoreMarkerData[]>([])
  const [facilities, setFacilities] = useState<FacilityMarkerData[]>([])
  const [storeMarkers, setStoreMarkers] = useState<any[]>([])
  const [facilityMarkers, setFacilityMarkers] = useState<any[]>([])

  // 绑定模态框状态
  const [isStoreModalOpen, setIsStoreModalOpen] = useState(false)
  const [isFacilityModalOpen, setIsFacilityModalOpen] = useState(false)
  const [bindingPosition, setBindingPosition] = useState<[number, number] | null>(null)
  const [bindingMeshInfo, setBindingMeshInfo] = useState<{
    name: string
    object: THREE.Object3D
    point: THREE.Vector3
  } | null>(null)

  // 坐标转换函数
  const getViewCp = (worldPosition: THREE.Vector3, targetV2: THREE.Vector2, camera: THREE.PerspectiveCamera) => {
    const vector = worldPosition.clone()
    vector.project(camera)
    targetV2.x = (vector.x + 1) / 2 * window.innerWidth
    targetV2.y = -(vector.y - 1) / 2 * window.innerHeight
    return targetV2
  }

  const coordsToLngLats = (viewPosition: THREE.Vector2, AMapClass: any, map: any, targetV2: THREE.Vector2) => {
    const pixel = new AMapClass.Pixel(viewPosition.x, viewPosition.y)
    const lnglat = map.pixelToLngLat(pixel)
    if (lnglat) {
      targetV2.set(lnglat.lng, lnglat.lat)
    } else {
      targetV2.copy(viewPosition)
    }
    return targetV2
  }

  // 初始化地图
  const initMap = useCallback(async () => {
    if (!containerRef.current || initOnceRef.current) return

    try {
      await AMapLoader.load({
        key: amapKey,
        version: '2.0',
        plugins: [],
        Loca: { version: '2.0.0' }
      })

      AMapRef.current = window.AMap

      const map = new window.AMap.Map(containerRef.current, {
        center: attraction?.center || [120.1551, 30.2741],
        zoom: zoom,
        viewMode: '3D',
        pitch: 45,
        rotation: 45,
        showLabel: false,
        features: ['bg', 'building']
      })

      mapRef.current = map
      initOnceRef.current = true

      // 初始化3D场景
      init3DScene()

      // 监听地图点击事件
      map.on('click', handleMapClick)

      setMapLoaded(true)
      console.log('地图初始化完成')

    } catch (error) {
      console.error('地图初始化失败:', error)
      setMapLoadFailed(true)
      setLoadError(error instanceof Error ? error.message : '地图加载失败')
    }
  }, [amapKey, attraction, zoom])

  // 初始化3D场景
  const init3DScene = () => {
    if (!mapRef.current) return

    const scene = sceneRef.current
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
    const renderer = new THREE.WebGLRenderer({ alpha: true })

    renderer.setSize(window.innerWidth, window.innerHeight)
    renderer.setClearColor(0x000000, 0)

    cameraRef.current = camera
    rendererRef.current = renderer

    // 添加模型组
    scene.add(modelGroupRef.current)

    // 添加光源
    const ambientLight = new THREE.AmbientLight(0x404040, 0.6)
    scene.add(ambientLight)

    const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8)
    directionalLight.position.set(100, 100, 50)
    scene.add(directionalLight)
  }

  // 加载3D模型
  const loadModel = useCallback(async (modelPath: string) => {
    if (!modelPath) return

    try {
      // 这里应该使用GLTFLoader加载模型
      // 为了示例，我们创建一个简单的立方体
      const geometry = new THREE.BoxGeometry(10, 10, 10)
      const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 })
      const cube = new THREE.Mesh(geometry, material)
      cube.name = 'building'
      
      // 清除之前的模型
      modelGroupRef.current.clear()
      modelGroupRef.current.add(cube)

      setModelLoaded(true)
      console.log('3D模型加载完成')
    } catch (error) {
      console.error('3D模型加载失败:', error)
      toast.error('3D模型加载失败')
    }
  }, [])

  // 处理地图点击事件
  const handleMapClick = useCallback((e: any) => {
    const lnglat: [number, number] = [e.lnglat.lng, e.lnglat.lat]
    
    // 射线检测Three.js对象
    const rayState = rayStateRef.current
    const camera = cameraRef.current
    if (!camera) return

    const mouse = rayState.mouse.clone()
    mouse.x = (e.originEvent.clientX / window.innerWidth) * 2 - 1
    mouse.y = -(e.originEvent.clientY / window.innerHeight) * 2 + 1

    rayState.raycaster.setFromCamera(mouse, camera)
    const intersections = rayState.raycaster.intersectObjects(modelGroupRef.current.children, true)

    if (intersections.length > 0) {
      const intersection = intersections[0]
      const mesh = intersection.object
      
      // 转换坐标
      const viewPoint = new THREE.Vector2()
      getViewCp(intersection.point, viewPoint, camera)
      
      const lnglat = new THREE.Vector2()
      coordsToLngLats(viewPoint, AMapRef.current, mapRef.current, lnglat)
      
      if (mesh.name === 'building') {
        // 点击在建筑上，绑定商铺
        setBindingPosition([lnglat.x, lnglat.y])
        setBindingMeshInfo({
          name: mesh.name,
          object: mesh,
          point: intersection.point
        })
        setIsStoreModalOpen(true)
        toast.success('点击建筑 - 绑定商铺信息')
      } else {
        // 点击在地面，绑定设施
        setBindingPosition([lnglat.x, lnglat.y])
        setBindingMeshInfo(null)
        setIsFacilityModalOpen(true)
        toast.success('点击地面 - 绑定设施信息')
      }
    } else {
      // 点击在地图上，绑定设施
      setBindingPosition(lnglat)
      setBindingMeshInfo(null)
      setIsFacilityModalOpen(true)
      toast.success('点击地图 - 绑定设施信息')
    }
  }, [])

  // 加载商铺数据
  const loadStores = useCallback(async () => {
    if (!attraction?.id) return

    try {
      const result = await getStoresByAttraction(attraction.id)
      if (result.success && result.data) {
        setStores(result.data)
        renderStoreMarkers(result.data)
      }
    } catch (error) {
      console.error('加载商铺数据失败:', error)
    }
  }, [attraction?.id])

  // 加载设施数据
  const loadFacilities = useCallback(async () => {
    if (!attraction?.id) return

    try {
      const result = await getFacilitiesByAttraction(attraction.id)
      if (result.success && result.data) {
        setFacilities(result.data)
        renderFacilityMarkers(result.data)
      }
    } catch (error) {
      console.error('加载设施数据失败:', error)
    }
  }, [attraction?.id])

  // 渲染商铺标记
  const renderStoreMarkers = (storeData: StoreMarkerData[]) => {
    if (!mapRef.current) return

    // 清除现有标记
    storeMarkers.forEach(marker => marker.setMap(null))

    const newMarkers = storeData.map(store => {
      const marker = new AMapRef.current.Marker({
        position: store.position,
        content: `<div style="
          background: #10b981;
          color: white;
          padding: 4px 8px;
          border-radius: 4px;
          font-size: 12px;
          white-space: nowrap;
          box-shadow: 0 2px 4px rgba(0,0,0,0.2);
        ">🏪 ${store.name}</div>`,
        offset: new AMapRef.current.Pixel(-30, -20)
      })

      marker.setMap(mapRef.current)
      
      // 点击事件
      marker.on('click', () => {
        toast.success(`商铺: ${store.name}`)
      })

      return marker
    })

    setStoreMarkers(newMarkers)
  }

  // 渲染设施标记
  const renderFacilityMarkers = (facilityData: FacilityMarkerData[]) => {
    if (!mapRef.current) return

    // 清除现有标记
    facilityMarkers.forEach(marker => marker.setMap(null))

    const newMarkers = facilityData.map(facility => {
      const marker = new AMapRef.current.Marker({
        position: facility.position,
        content: `<div style="
          background: #3b82f6;
          color: white;
          padding: 4px 8px;
          border-radius: 4px;
          font-size: 12px;
          white-space: nowrap;
          box-shadow: 0 2px 4px rgba(0,0,0,0.2);
        ">🏗️ ${facility.name}</div>`,
        offset: new AMapRef.current.Pixel(-30, -20)
      })

      marker.setMap(mapRef.current)
      
      // 点击事件
      marker.on('click', () => {
        toast.success(`设施: ${facility.name}`)
      })

      return marker
    })

    setFacilityMarkers(newMarkers)
  }

  // 外部调用接口
  useImperativeHandle(ref, () => ({
    refreshStores: loadStores,
    refreshFacilities: loadFacilities,
    refreshModel: () => {
      if (attraction?.modelPath) {
        loadModel(attraction.modelPath)
      }
    },
    flyTo: (lngLat: [number, number], zoom = 16) => {
      if (mapRef.current) {
        mapRef.current.setCenter(lngLat)
        mapRef.current.setZoom(zoom)
      }
    }
  }))

  // 初始化和数据加载
  useEffect(() => {
    initMap()
  }, [initMap])

  useEffect(() => {
    if (attraction && mapLoaded) {
      if (attraction.modelPath) {
        loadModel(attraction.modelPath)
      }
      loadStores()
      loadFacilities()
      
      // 移动地图到景区中心
      if (mapRef.current) {
        mapRef.current.setCenter(attraction.center)
      }
    }
  }, [attraction, mapLoaded, loadModel, loadStores, loadFacilities])

  // 处理绑定成功
  const handleStoreBindingSuccess = () => {
    loadStores()
    onDataChange?.()
    setBindingPosition(null)
    setBindingMeshInfo(null)
  }

  const handleFacilityBindingSuccess = () => {
    loadFacilities()
    onDataChange?.()
    setBindingPosition(null)
  }

  if (mapLoadFailed) {
    return (
      <div className={`flex items-center justify-center bg-gray-100 ${className}`}>
        <div className="text-center">
          <div className="text-red-500 mb-2">⚠️ 地图加载失败</div>
          <div className="text-sm text-gray-600">{loadError}</div>
        </div>
      </div>
    )
  }

  return (
    <div className={className}>
      <div ref={containerRef} className="w-full h-full" />
      
      {/* 绑定模态框 */}
      {attraction && (
        <>
          <StoreBindingModal
            isOpen={isStoreModalOpen}
            onClose={() => {
              setIsStoreModalOpen(false)
              setBindingPosition(null)
              setBindingMeshInfo(null)
            }}
            attractionId={attraction.id}
            position={bindingPosition || undefined}
            meshInfo={bindingMeshInfo || undefined}
            onSuccess={handleStoreBindingSuccess}
          />

          <FacilityBindingModal
            isOpen={isFacilityModalOpen}
            onClose={() => {
              setIsFacilityModalOpen(false)
              setBindingPosition(null)
            }}
            attractionId={attraction.id}
            position={bindingPosition || undefined}
            onSuccess={handleFacilityBindingSuccess}
          />
        </>
      )}
    </div>
  )
})